home *** CD-ROM | disk | FTP | other *** search
/ MacHack 2000 / MacHack 2000.toast / pc / The Hacks / Genie / Projects / A-line / Scripts / MakeDepend.pl < prev    next >
Encoding:
Perl Script  |  2000-06-24  |  4.2 KB  |  185 lines

  1. #!perl -w
  2. undef;
  3.  
  4. # MakeDepend
  5.  
  6. use strict;
  7.  
  8. use FileHandle;
  9.  
  10. use SourceList;
  11. use SCF;
  12.  
  13. unless (@ARGV) {
  14.     @ARGV = ('--target');
  15. }
  16. my %DEFS = (
  17.     'i' => {OPT => 'incdir'},
  18.     's' => {OPT => 'srcdir'},
  19.     't' => {OPT => 'target'},
  20.     incdir => {OPT => 'incdir', ARG => 1, MULTI => 'list'},
  21.     srcdir => {OPT => 'srcdir', ARG => 1, MULTI => 'list'},
  22.     target => {OPT => 'target'},
  23.     scf => {OPT => 'scf'},
  24.     srclist => {OPT => 'srclist'},
  25. );
  26. my %OPTS = GetOpts(\%DEFS);
  27.  
  28. $OPTS{target} and $OPTS{scf} = $OPTS{srclist} = 1;
  29.  
  30. my @files;
  31. if ($OPTS{srclist}) {
  32.     my $sources = SourceList::Sources(":Manifest:Source.list");
  33.     push @files, map { $_->{DIR} . $_->{FILE} } @$sources;
  34. }
  35. if ($OPTS{scf}) {
  36.     my $SCF = SCF::Read(":Manifest:Imports.scf");
  37.     my %srcdirs = SCF::Collect($SCF, "Sources");
  38.     if ($OPTS{srclist}) {
  39.         foreach my $intf (keys %srcdirs) {
  40.             push @files, map { TargetDir($intf, "Menu") . "Sources:$_" }
  41.                 split(' ', $srcdirs{$intf});
  42.         }
  43.     }
  44.     my %incdirs = (SCF::Collect($SCF, "Include"), SCF::Collect($SCF, "SysInclude"));
  45.     push @{$OPTS{incdir}}, map { TargetDir($_, "Menu") . "Includes:" } keys %incdirs;
  46. }
  47. push @files, @ARGV;
  48. MakeDepend(@files);
  49.  
  50. my %Incs;
  51.  
  52. sub TargetDir {
  53.     my ($target, $dir) = @_;
  54.     # Assumes MPW environment
  55.     $dir ||= "Menu";
  56.     my $pathname = "$ENV{Boot}Development:$dir:$target";
  57.     my $original = readlink($pathname);
  58.     defined $original or die "Missing alias '$pathname'";
  59.     -d $original or die "Stale alias '$pathname'";
  60.     return $original . ':';
  61. }
  62.  
  63. sub GetOpts {
  64.     my ($defs) = @_;
  65.     my %opts;
  66.     my @args;
  67.     while ($_ = shift @ARGV) {
  68.         last if /^--$/;
  69.         if (/^--(\w+)(=?)(.*)/) {
  70.             exists $defs->{$1} or die "$0: unknown option '--$1'";
  71.             my $opt = $defs->{$1}{OPT};
  72.             my $value = $defs->{$opt}{ARG} ? $2 ? $3 : shift @ARGV : undef;
  73.             if ($defs->{$opt}{MULTI}) {
  74.                 push @{$opts{$opt}}, $value;
  75.             } else {
  76.                 $opts{$opt} = defined $value ? $value : 1;
  77.             }
  78.         } elsif (/^-(\w*)/) {
  79.             my @opts = split '', $1;
  80.             foreach (@opts) {
  81.                 exists $defs->{$_} or 
  82.                     die "qui: unknown option '-$_' in '-$1'";
  83.                 my $opt = $defs->{$_}{OPT};
  84.                 my $value = $defs->{$opt}{ARG} ? shift @ARGV : 1;
  85.                 if ($defs->{$opt}{MULTI} eq 'list') {
  86.                     push @{$opts{$opt}}, $value;
  87.                 } else {
  88.                     $opts{$opt} = defined $value ? $value : 1;
  89.                 }
  90.             }
  91.         } else {
  92.             push @args, $_;
  93.         }
  94.     }
  95.     push @args, @ARGV;
  96.  
  97.     @ARGV = @args;
  98.     return %opts;
  99. }
  100.  
  101. sub Basename {
  102.     my ($name) = @_;
  103.     $name =~ s/^(?:.*:)?(.+?):?$/$1/;
  104.     return $name;
  105. }
  106.  
  107. sub Search {
  108.     my ($filename) = @_;
  109.     $filename =~ /:/ and return $filename;
  110.     foreach (@{$OPTS{incdir}}, @{$OPTS{srcdir}}) {
  111.         s/:?$/:/;
  112.         my $path = $_ . $filename;
  113.         -e $path and return $path;
  114.     }
  115.     return undef;
  116. }
  117.  
  118. sub ScanForIncludes {
  119.     my ($file, $src) = @_;
  120.     my $path = Search($file) or die "Missing file '$file' included by '$src'";
  121.     my @includes;
  122.     open FILE, $path or die "Error opening file '$file': ($!)";
  123.     while (<FILE>) {
  124.         /^\s*\#\s*include\s+(.*)/ or next;
  125.         my $include = $1;
  126.         $include =~ /^<[^>]+>/ and next;
  127.         $include =~ /^"([^"]+)"\s*$/ or warn "Bad include: '$_'", next;
  128.         push @includes, $1;
  129.     }
  130.     close FILE or die "Error closing file '$file': ($!)";
  131.     return @includes;
  132. }
  133.  
  134. sub LearnIncludes {
  135.     my ($file, $src) = @_;
  136.     return if exists $Incs{Basename($file)};
  137.     my @includes = ScanForIncludes($file, $src);
  138.     $Incs{Basename($file)} = [@includes];
  139.     foreach (@includes) {
  140.         LearnIncludes($_, $file);
  141.     }
  142. }
  143.  
  144. sub Unique {
  145.     my @list;
  146.     my $item;
  147.     while ($item = shift) {
  148.         push @list, $item unless grep {$_ eq $item} @list;
  149.     }
  150.     return @list;
  151. }
  152.  
  153. sub Deps {
  154.     my ($file) = @_;
  155.     my @incs = @{$Incs{$file}};
  156.     foreach (@incs) {
  157.         push @incs, Deps($_);
  158.     }
  159.     return Unique(@incs);
  160. }
  161.  
  162. sub MakeDeps {
  163.     my ($file) = @_;
  164.     LearnIncludes($file, 'ROOT');
  165.     my $base = Basename($file);
  166.     my @deps = Deps($base);
  167.     my ($dfile, $objfile);
  168.     ($dfile = $base) =~ s/\..+?$/.d/;
  169.     ($objfile = $base) =~ s/\..+?$/.o/;
  170.     return join(' ', $dfile, $objfile, ':', $base, @deps);
  171. }
  172.  
  173. sub MakeDepend {
  174.     #print "# Make dependencies generated automatically by MakeDepend.\n\n";
  175.     foreach my $pathname (@_) {
  176.         my $deps = MakeDeps($pathname);
  177.         my $base = Basename($pathname);
  178.         (my $dfile = $base) =~ s/\..+?$/.d/;
  179.         my $fh = new FileHandle ":[Dependencies]:$dfile", ">";
  180.         defined $fh or die "Couldn't make new FileHandle";
  181.         print $fh $deps, "\n";
  182.     }
  183. }
  184.  
  185.